<template>
  <div>
    <div class="draggle-table" v-if="cloneColumns.length">
      <el-table
        v-loading="isLoading"
        :data="tableData"
        :max-height="maxHeight"
        size="small"
        border
        @sort-change="tableSortChange"
        :class="[tableData.length === 0 && 'empty-fixed']"
      >
        <el-table-column
          type="index"
          label="序号"
          fixed="left"
          align="center"
        >
          <template slot="header">
            <span
              refs="setIcon"
              class="iconfont icon-a-shezhi"
              @click="showModal"
            ></span>
          </template>
        </el-table-column>
        <el-table-column
          align="center"
          :fixed="onHandleFixed(item.fixed)"
          :label="item.title"
          :min-width="columnMinWidth"
          :show-overflow-tooltip="true"
          v-for="item in onFilterClumns(this.cloneColumns)"
          :key="item.keyField"
          :sortable="item.sortable === JUDGE.yes ? 'custom' : false"
          :prop="item.keyField"
        >
          <template slot-scope="scope">
            <span v-if="item.keyField === 'operation'">
              <slot name="operation" :scope="scope"></slot>
            </span>
            <span v-else-if="item.link === JUDGE.yes">
              <slot name="link" :scope="scope"></slot>
            </span>
            <span v-else-if="item.extend === JUDGE.yes">
              <slot name="extend" :scope="scope"></slot>
            </span>
            <span v-else>
              {{ scope.row[item.keyField] }}
            </span>
          </template>
        </el-table-column>
      </el-table>
      <div class="page-type">
        <el-pagination
          background
          layout="total, prev, pager, next, sizes, jumper"
          :total="pagination.total"
          :current-page.sync="pagination.currentPage"
          :page-size="pagination.pageSize"
          @current-change="handleCurrentChange"
          @size-change="onPageSize"
        >
        </el-pagination>
      </div>
      <div v-if="tableSetVisible" class="set-modal" ref="setModal">
        <div class="drag-modal">
          <div class="drag-contain beauty-scroll">
            <draggable
              :animation="150"
              filter=".unmover"
              handle=".mover"
              v-model.trim="totalColumns"
              :scrollSpeed="2"
              class="mt10"
              :move="onMove"
            >
              <div
                v-for="(item, idx) in totalColumns"
                :key="item.title"
                :class="item.defaultChecked === JUDGE.yes && 'unmover'"
              >
                <sort-item
                  :isChecked="mapChecked[item.title]"
                  :defaultChecked="item.defaultChecked === JUDGE.yes"
                  :title="item.title"
                  @onChecked="onChecked"
                  @click.native="onSetFrozen(idx, item.defaultChecked)"
                >
                  <img
                    class="frozen-type"
                    src="@/assets/img/affix.png"
                    v-if="currentFrozenIndex === idx"
                  />
                </sort-item>
              </div>
            </draggable>
          </div>
          <div class="confirm-btn">
            <a-button class="mr10" @click="handleCancel">取消</a-button>
            <a-button type="primary" @click="handleConfirm">确认</a-button>
          </div>
        </div>
      </div>
    </div>
    <a-empty class="empty-type" v-else />
  </div>
</template>

<script>
import Draggable from "vuedraggable";
import SortItem from "./SortItem.vue";
import {
  saveColumns,
  savePageSize,
  getColumns
} from "@/services/businessManage";
import cloneDeep from "lodash.clonedeep";
import moment from "moment";

const JUDGE = {
  yes: 1,
  no: 2
};
const space = 400;
export default {
  name: "DraggableTable",
  inject: ["reload"],
  data() {
    return {
      JUDGE,
      moment,
      tableSetVisible: false,
      totalColumns: [],
      cloneColumns: [],
      currentFrozenIndex: 0,
      mapChecked: {},
      isCheckedMap: {
        true: 1,
        false: 2
      },
      maxHeight: window.innerHeight - space
    };
  },
  components: {
    SortItem,
    Draggable
  },
  props: {
    tableData: {
      type: Array,
      default() {
        return [];
      }
    },
    linkDetail: {
      type: String,
      default: ""
    },
    isLoading: {
      type: Boolean,
      default: false
    },
    pagination: {
      type: Object,
      default() {
        return {
          total: 0,
          pageSize: 10,
          currentPage: 1
        };
      }
    },
    pageType: {
      type: String,
      default: ""
    },
    columnMinWidth: {
      type: Number,
      default: 150
    }
  },
  mounted() {
    this.getColumns();
    // 操作-表头弹框 点击弹框以外关闭弹框
    this.onMonitorModal();
    // this.onMonitorTableHeight();
  },
  methods: {
    onMonitorTableHeight() {
      window.onresize = () => {
        this.maxHeight = window.innerHeight - space;
      }
    },
    onHandleFixed(val) {
      return val === "left";
    },
    onMonitorModal() {
      document.addEventListener("mouseup", (e) => {
        let tree = this.$refs.setModal;
        let flag = e?.target?.getAttribute("refs") !== "setIcon";
        if (tree && !tree.contains(e.target) && flag) {
          this.tableSetVisible = false;
        }
      });
    },
    async getColumns() {
      const {
        data: { data, code }
      } = await getColumns({ page: this.pageType });
      if (code === 200) {
        (data.queryTitles || []).forEach(
          (o) => (o.checked = o.checked === JUDGE.yes)
        );
        this.totalColumns = data.queryTitles || [];
        this.cloneColumns = cloneDeep(this.totalColumns);
        this.handleDisabled(data);
        this.createClumns();
      }
    },
    handleDisabled(data) {
      let obj = {};
      this.totalColumns.forEach((o) => {
        obj[o.keyField] =
          o.defaultChecked === 1 ? false : !o.checked;
      });
      this.$emit("triggerTableList", data, obj);
    },
    createClumns() {
      let fixedList = this.totalColumns.filter((v) => v.fixed === "left");
      this.currentFrozenIndex = fixedList.length || 0;
      this.onMapChecked();
    },
    onFilterClumns(data) {
      let arr = data.filter((o) => o.checked || o.defaultChecked === JUDGE.yes);
      return arr;
    },
    // table 排序 change
    tableSortChange(column) {
      this.$emit("sort-change", column);
    },
    indexMethod(index) {
      return index + 1;
    },
    async onPageSize(pageSize) {
      this.$emit("size-change", pageSize);
      let params = {
        page: this.pageType,
        size: pageSize
      };
      const {
        data: { code }
      } = await savePageSize(params);
      if (code === 200) {
        this.tableSetVisible = false;
      }
    },
    handleCurrentChange(page) {
      this.$emit("current-change", page);
    },
    onMapChecked() {
      this.totalColumns.forEach((o) => {
        if (o.checked) {
          this.$set(this.mapChecked, o.title, o.checked);
        }
      });
    },
    handleCancel() {
      this.tableSetVisible = false;
    },
    handleConfirm() {
      let checkedArr = [];
      for (let key in this.mapChecked) {
        if (this.mapChecked[key]) {
          checkedArr.push(key);
        }
      }
      this.totalColumns.forEach(
        (o) =>(o.checked = o.defaultChecked === JUDGE.yes || checkedArr.includes(o.title))
      );
      // 针对表头固定的处理
      this.fixedColumns();
    },
    fixedColumns() {
      this.totalColumns.forEach(
        (o, i) => (o.fixed = i < this.currentFrozenIndex ? "left" : "")
      );
      this.onSaveColumns();
    },
    // 保存表头
    async onSaveColumns() {
      this.cloneColumns = cloneDeep(this.totalColumns);
      let arr = cloneDeep(this.totalColumns);
      arr.forEach((o) => (o.checked = this.isCheckedMap[o.checked]));
      let params = {
        freeze: 0,
        page: this.pageType,
        queryTitle: arr
      };
      const {
        data: { message, code }
      } = await saveColumns(params);
      if (code === 200) {
        this.$message.success('保存成功');
        this.tableSetVisible = false;
        this.reload();
      } else {
        this.$message.error(message || '保存失败');
      }
    },
    onSetFrozen(idx, defaultChecked) {
      if (defaultChecked === JUDGE.yes) {
        return false;
      }
      this.currentFrozenIndex = idx;
    },
    onChecked(params) {
      this.$set(this.mapChecked, params, !this.mapChecked[params]);
    },
    showModal() {
      if (!this.totalColumns.length) return;
      this.tableSetVisible = !this.tableSetVisible;
    },
    //禁止拖动默认表头
    onMove(e) {
      return e.relatedContext.element.defaultChecked !== JUDGE.yes;
    },
    formatDate(v, dateFormatType) {
      if(!dateFormatType) dateFormatType = "YYYY-MM-DD HH:mm:ss"
      // 根据传值，展示不同的日期时间格式
      return v ? moment(v).format(dateFormatType) : "--";
      /*
      格式如下：
      let dateFormatType = {
        time: "YYYY-MM-DD HH:mm:ss",
        day: "YYYY-MM-DD",
        month: "YYYY-MM",
        year: "YYYY"
      }
      */
    }
  }
};
</script>

<style lang="less" scoped>
.draggle-table {
  position: relative;

  .icon-a-shezhi {
    cursor: pointer;
  }

  .page-type {
    display: flex;
    justify-content: flex-end;
    margin-top: 10px;
  }

  .set-modal {
    width: 280px;
    position: absolute;
    background: #fff;
    left: 40px;
    top: 0;
    z-index: 999;
    padding: 10px;
    border: 1px solid #eee;

    ::v-deep .ant-tabs-tabpane {
      & > div {
        margin-bottom: 10px;
      }
    }

    .frozen-type {
      position: absolute;
      top: -10px;
      right: 0;
      width: 23px;
      height: 25px;
    }
  }

  .drag-modal {
    .unmover {
      & > .sort-list-group {
        cursor: not-allowed;
      }
    }
    .confirm-btn {
      margin-top: 10px;
      text-align: right;
    }

    .drag-contain {
      height: 300px;
      overflow-y: scroll;
      padding-right: 10px;
    }

    ::-webkit-scrollbar {
      width: 2px;
      height: 4px;
    }

    ::-webkit-scrollbar-track {
      -webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
      border-radius: 0;
      background: rgba(172, 172, 175, 0.6);
    }

    ::-webkit-scrollbar-thumb {
      background-color: #6e6e6e;
    }
  }

  .empty-fixed {
    ::v-deep .el-table__body-wrapper {
      z-index: 2;
    }
  }
}
.empty-type {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  height: 60vh;
}
</style>
